Skip to content

[ROCm][Quantization] Implement Fp8Config shared-expert FSE compatibility check - #53068

Open
jin-amd wants to merge 1 commit into
vllm-project:mainfrom
jin-amd:rocm-fse-fp8-shared-experts
Open

[ROCm][Quantization] Implement Fp8Config shared-expert FSE compatibility check#53068
jin-amd wants to merge 1 commit into
vllm-project:mainfrom
jin-amd:rocm-fse-fp8-shared-experts

Conversation

@jin-amd

@jin-amd jin-amd commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Purpose

is_shared_expert_quant_fse_compatible() gates AITER fused shared experts (FSE) behind a
quantization compatibility check that currently implements only QuarkConfig and
DeepseekV4FP8Config. Every other quantization falls through to a catch-all rejection:

shared-expert FSE quantization compatibility is not implemented for Fp8Config

The practical effect is that models loading with the plain Fp8Config accept
VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=1 and then silently run unfused. There is no error
and no non-zero exit, only one warning per MoE layer per rank buried in startup logs. On
GLM-5.2-FP8 (78 MoE layers, TP8) that is 600+ near-identical warning lines, and it is easy to
believe the flag took effect when it did not.

This PR implements the TODO that sits directly above the catch-all return:

# TODO: Extend FSE support detection to other quantization methods. Typically,
# one would check that the experts and shared_experts use the same
# quantization config.

Fp8Config carries a single global weight_block_size and activation_scheme with no
per-layer overrides, so the only source of per-layer variation is ignored_layers. Routed and
shared experts therefore share a quantization config exactly when they are either both
quantized or both ignored. Skip status is resolved with is_layer_skipped() using the config's
own packed_modules_mapping and ignored_layers_match_mode — the same call
Fp8Config.get_quant_method() makes — so the check asks the quantization layer the question it
already asks itself rather than inventing a parallel rule.

The branch fails closed: any asymmetry between the routed and shared experts returns False
with a reason mirroring the existing Quark message. It is also restricted to fp8-serialized
checkpoints, since the online-quantization path has not been exercised. It is placed below the
DeepseekV4FP8Config branch, which subclasses Fp8Config and needs its own MXFP4 handling.

Other quantizations (compressed-tensors, GPTQ, AWQ, ModelOpt) still fall through the catch-all
and are unaffected.

Test Plan

Unit:

pytest tests/model_executor/layers/test_fused_shared_expert.py -k fp8

Seven new cases extend the existing gate tests: uniformly quantized experts, non-expert
exclusions (layernorms, mlp.gate, lm_head) which must not disable FSE, both expert groups
ignored, three asymmetric-exclusion negative controls (shared excluded, routed excluded, one of
two projections excluded), and a non-serialized checkpoint.

End to end, zai-org/GLM-5.2-FP8, 8x MI325X (gfx942), TP8, vllm bench serve with random
131,072 input / 1,024 output, 20 prompts, seed 4, 2 warmups:

VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_MOE=1 \
VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=1 \
vllm serve zai-org/GLM-5.2-FP8 -tp 8 --block-size 64 --gpu-memory-utilization 0.83

Test Result

Unit tests: 7 new cases pass with the change and all 7 fail without it. The 14 pre-existing
non-GPU cases in the same module continue to pass.

End to end the flag now takes effect: the per-layer cannot be enabled warning is gone, KV
cache size is unchanged at 2,240,512 tokens, AITER block-scale FP8 MoE kernels are selected
(fmoe_bf16_blockscaleFp8_g1u1_vs_silu_*), and output is correct on arithmetic, factual recall
and text completion prompts.

Output token throughput, FSE off vs on:

Concurrency off on change
8 84.85 91.74 +8.1%
6 79.19 84.07 +6.2%
4 76.01 82.45 +8.5%
2 60.47 59.83 −1.1%

Latency, FSE off → on:

Conc. Mean TTFT (ms) Mean TPOT (ms) Mean E2EL (ms)
8 31,173 → 28,759 (−7.7%) 59.52 → 55.26 (−7.2%) 92,061 → 85,285 (−7.4%)
6 25,854 → 23,360 (−9.6%) 46.38 → 44.23 (−4.6%) 73,295 → 68,606 (−6.4%)
4 22,814 → 20,321 (−10.9%) 30.34 → 28.66 (−5.5%) 53,852 → 49,642 (−7.8%)
2 14,403 → 13,301 (−7.6%) 19.02 → 20.45 (+7.5%) 33,864 → 34,225 (+1.1%)

TTFT improves at every concurrency because prefill always presents the fused grouped GEMM with
a large token batch. TPOT improves at concurrency 4 and above but regresses 7.5% at concurrency
2, where the decode batch is too small to amortize the fused kernel and a dedicated dense GEMM
for the single shared expert wins; there the prefill gain and decode loss roughly cancel. The
crossover lies between concurrency 2 and 4. Concurrency 2 was measured twice on separate days
with a server restart between, agreeing to within 0.05%, so these deltas are signal rather than
noise.

`is_shared_expert_quant_fse_compatible` currently implements only
`QuarkConfig` and `DeepseekV4FP8Config`; every other quantization falls
through to a catch-all rejection. Models that load with the plain
`Fp8Config` therefore accept
`VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=1` and then silently run
unfused, emitting one warning per MoE layer per rank.

Implement the existing TODO for `Fp8Config`. The config carries a single
global `weight_block_size` and `activation_scheme`, so routed and shared
experts share a quantization config exactly when they are either both
quantized or both listed in `ignored_layers`. Skip status is resolved
with `is_layer_skipped()` using the config's own
`packed_modules_mapping` and `ignored_layers_match_mode`, which is the
same call `Fp8Config.get_quant_method()` makes. The branch is restricted
to fp8-serialized checkpoints and fails closed on any asymmetry.

Signed-off-by: Jin Tao <jin.tao@amd.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions

Copy link
Copy Markdown

👋 Hi! Thank you for contributing to the vLLM project.

💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in #pr-reviews, coordinate on features in #feat- channels, or join special interest groups in #sig- channels.

PRs do not trigger a full CI run by default. Reviewers with write access and configured trusted contributors can comment /ci run for upstream CI or /amd-ci run for AMD CI only whenever CI signals are needed.

Once the PR is approved or has the ready label, the PR author can also use the corresponding /ci run, /ci retry, and /ci cancel commands, or their /amd-ci variants. New commits do not start upstream CI automatically.

If you have any questions, please reach out to us on Slack at https://slack.vllm.ai.

Agent Guidelines

IMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban.

🚀

@mergify mergify Bot added quantization rocm Related to AMD ROCm labels Aug 20, 2026
@github-project-automation github-project-automation Bot moved this to Todo in AMD Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

quantization rocm Related to AMD ROCm

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant